Redux-Saga 基礎概念要結束啦~
就來看看他最後兩篇章節吧
可以利用 try
/catch
中處理 API 錯誤,或是透過API回的response情況來使用if
/else
判斷
function* fetchProducts() {
try {
const products = yield call(Api.fetch, '/products')
yield put({ type: 'PRODUCTS_RECEIVED', products })
}
catch(error) {
yield put({ type: 'PRODUCTS_REQUEST_FAILED', error })
}
}
function fetchProductsApi() {
return Api.fetch('/products')
.then(response => ({ response }))
.catch(error => ({ error }))
}
function* fetchProducts() {
const { response, error } = yield call(fetchProductsApi)
if (response)
yield put({ type: 'PRODUCTS_RECEIVED', products: response })
else
yield put({ type: 'PRODUCTS_REQUEST_FAILED', error })
}
其他情況:
onError hook
錯誤發生的最後手段,error跑到rootSaga時,整個saga就會被停下,這時就可以使用onError,通知用戶且終止程式。
saga的輔助函數(監控特定 Action)
keywords: takeEvery
, takeLatest
, take
takeEvery
:每次觸發相同type 的 action 時都會執行 fetchData
,是最常見的,它提供了類似 redux-thunk 的行為。import { takeEvery } from 'redux-saga/effects'
function* fetchData() { ... }
export function* watchGetStores() {
yield takeEvery (getStores.type, fetchData);
}
import { takeEvery } from 'redux-saga/effects'
// FETCH_USERS
function* fetchUsers(action) { ... }
// CREATE_USER
function* createUser(action) { ... }
// use them in parallel
export default function* rootSaga() {
yield takeEvery('FETCH_USERS', fetchUsers)
yield takeEvery('CREATE_USER', createUser)
}
takeLatest
:只想獲得最新請求的回覆(response),始終顯示最新版本的數據。多次觸發相同 type 的 action 時,會以最後一次的回應為準,在之前還未完成(如,pending)的 fetchData
將會被取消。import { all, call, put, takeEvery, takeLatest } from 'redux-saga/effects';
function* fetchData() { ... }
export function* watchGetStores() {
yield takeLatest(getStores.type, fetchData);
}
take
:透過 take
可以持續監聽某一 action,並且從該 yield 的 function 可以取得 action 的 payload
。(下方pass)takeEvery
和 takeLatest
都是透過 take
(Lower level API)這個方法所包出來的 higher level API。當我們使用 call
時在 middleware 的地方會停住 Saga,直到 Promise 被 resolve;使用 take
時類似,它會停住 saga 直到對應的 action 被 dispatch 後才繼續。function* watchFetchData() {
while (true) {
const action = yield take('FETCH_REQUESTED');
// 做原本 fetch Data 要執行的動作 ...
}
}
留意這裡用的 while (true) { … }
的寫法,因為 watchFetchData
是一個 Generator function,透過 while (true)
的寫法可以讓這個 Generator function 不會進到 done: true
的情況,因此每次疊代時都會等待該 action 產生。
如果沒有加上 while (true) 這個 Generator function 產生的 iterator 將執行一輪後就結束了,如此將只會監聽到一次該 action 的發生,之後便無法持續監聽某一 action。
結語:
明天將會實際來介紹一遍實際coding 範例~